﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace ProcessX
{
    public partial class Form1 : QT.Windows.Shell.GlassForm
    {
        protected System.Timers.Timer myTimer = new System.Timers.Timer();

        public Form1()
        {
            InitializeComponent();
            loadForm();
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            if (this.cbAutoMonitor.Checked) btnStart_Click(this.btnStart, e);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            e.Cancel = true;
            if (myTimer.Enabled && MessageBox.Show("程序正在运行，确认要关闭吗?", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) return;
            e.Cancel = false;
        }

        private void pbOpenFile_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog myFolderDialog = new FolderBrowserDialog();
            if (myFolderDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbLogPath.Text = myFolderDialog.SelectedPath;
            }
            myFolderDialog.Dispose();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (this.tbLogPath.Text.Length == 0)
            {
                MessageBox.Show("请选择日志路径");
                return;
            }
            if (this.tbProcesses.Text.Length == 0)
            {
                MessageBox.Show("请输入要关闭的进程名称");
                return;
            }

            Configuration appConfig = null;
            try
            {
                appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                appConfig.AppSettings.Settings["Time"].Value = this.dtpTime.Value.ToString("HH:mm:ss");
                appConfig.AppSettings.Settings["Processes"].Value = this.tbProcesses.Text;
                appConfig.AppSettings.Settings["LogPath"].Value = this.tbLogPath.Text;
                appConfig.AppSettings.Settings["AutoMonitor"].Value = this.cbAutoMonitor.Checked ? "1" : "0";
                appConfig.AppSettings.Settings["IsShutDown"].Value = this.cbShutDown.Checked ? "1" : "0";
                appConfig.Save();
                if (SetAutoRun(cbAutoRun.Checked)) MessageBox.Show("保存成功");
                else MessageBox.Show("登陆启动保存失败");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {

                if (appConfig != null) appConfig = null;
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            ConfigurationManager.RefreshSection("appSettings");
            setControl(false);

            try
            {
                myTimer.Interval = 1000;
                myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
                myTimer.Start();
            }
            catch (Exception ex)
            {
                OutLog(ex.Message);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.myTimer.Stop();
            setControl(true);
        }

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            TimeSpan diffTime = this.dtpTime.Value.Subtract(DateTime.Now);
            if (diffTime.TotalMilliseconds < 1)
            {
                KillProcess();
                myTimer.Stop();
                setControl(true);
            }
        }

        private void KillProcess()
        {
            Process[] processes = Process.GetProcesses();
            List<string> myProcesses = new List<string>(this.tbProcesses.Text.ToLower().Split('|'));
            foreach (Process p in processes)
            {
                try
                {
                    if (myProcesses.Contains(p.MainModule.ModuleName.ToLower()))
                    {
                        int WM_QUIT = 18;
                       // SafeNativeMethods.ShowWindow(p.MainWindowHandle, 1|5|8);
                        SafeNativeMethods.SendMessage(p.MainWindowHandle, WM_QUIT, 45, 0);
                        //MessageBox.Show(rval.ToString());
                        //if (!p.CloseMainWindow()) MessageBox.Show("进程关闭失败：" + p.MainModule.ModuleName);
                    }
                }
                catch
                {
                    continue;
                }
            }

            if (this.cbShutDown.Checked)
            {
                Process.Start("shutdown.exe", "-f -s -t 120");
                OutLog("120秒后关机");
            }
        }

        private bool SetAutoRun(bool b)
        {
            //打开注册表
            RegistryKey regKey = Registry.CurrentUser;
            string SubKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
            RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);
            if (optionKey == null)
            {
                MessageBox.Show(@"注册表打开失败");
                return false;
            }

            
            try
            {
                if (b)
                {
                    optionKey.SetValue("ProcessX", Application.ExecutablePath);
                }
                else
                {
                    optionKey.DeleteValue("ProcessX", false);
                }
            }
            catch
            {
                optionKey.Close();
                MessageBox.Show("登陆启动设置失败");
                return false;
            }

            return true;
        }

        private bool GetAutoRun()
        {
            //打开注册表
            RegistryKey regKey = Registry.CurrentUser;
            string SubKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
            RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);
            if (optionKey == null)
            {
                MessageBox.Show(@"注册表打开失败");
                return false;
            }

            try
            {
                if (optionKey.GetValue("ProcessX", "false").ToString().ToLower() == "false") return false;
                return true;
            }
            catch
            {
                regKey.Close();
                return false;
            }
        }

        private void loadForm()
        {
            try
            {
                this.dtpTime.Value = DateTime.Parse(ConfigurationManager.AppSettings["Time"]); 
            }
            catch
            {
            }
            try
            {
                this.tbProcesses.Text = ConfigurationManager.AppSettings["Processes"];
                this.tbLogPath.Text = ConfigurationManager.AppSettings["LogPath"];
                this.cbAutoMonitor.Checked = ConfigurationManager.AppSettings["AutoMonitor"] == "1" ? true : false;
                this.cbShutDown.Checked = ConfigurationManager.AppSettings["IsShutDown"] == "1" ? true : false;
            }
            catch
            {
            }

            this.cbAutoRun.Checked = GetAutoRun();
        }

        private void OutLog(string txt)
        {
            FileStream fs = null;
            StreamWriter text = null;
            string LogFile = this.tbLogPath + @"\ShutDownX.log";

            try
            {
                fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write, FileShare.Read);
                text = new StreamWriter(fs);
                text.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]" + txt);
                text.Flush();
            }
            catch
            {
            }
            finally
            {
                if (fs != null) fs.Dispose();
            }
        }

        private void setControl(bool b)
        {
            this.groupBox1.Enabled = b;
            this.btnSave.Enabled = b;
            this.btnStart.Enabled = b;
            this.btnCancel.Enabled = !b;
        }
    }

    [SuppressUnmanagedCodeSecurity]
    internal static class SafeNativeMethods
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

        [DllImport("user32.dll", EntryPoint = "FindWindowA", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
        public static extern IntPtr FindWindowA(string lp1, string lp2);

        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr ShowWindow(IntPtr hWnd, int _value);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    }

}
